{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy.fft import fft\n",
    "from numpy import linspace, sin, pi, power, ceil, log2, arange, random\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Python 中 FFT 快速傅里叶分析\n",
    "## https://zhuanlan.zhihu.com/p/70347734"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def fft_func(fs, data):\n",
    "    len_ = len(data)\n",
    "    n = int(power(2, ceil(log2(len_))))\n",
    "    fft_y_ = (fft(y, n)) / len_ * 2\n",
    "    fre_ = arange(int(n / 2)) * fs / n\n",
    "    fft_y_ = fft_y_[range(int(n / 2))]\n",
    "    return fre_, fft_y_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "if __name__ == '__main__':\n",
    "    Fs = 10000\n",
    "    f1 = 390\n",
    "    f2 = 2e3\n",
    "\n",
    "    noise1 = random.random(Fs)\n",
    "    noise2 = random.normal(1, 10, Fs)\n",
    "\n",
    "    t = linspace(0, 1, Fs)\n",
    "    y = 2 * sin(2 * pi * f1 * t) + 5 * sin(2 * pi * f2 * t)\n",
    "    # y = 2 * sin(2 * pi * f1 * t) + 5 * sin(2 * pi * f2 * t) + noise2\n",
    "\n",
    "    fre, fft_y = fft_func(Fs, y)\n",
    "    plt.figure()\n",
    "    plt.plot(fre, abs(fft_y))\n",
    "    plt.grid()\n",
    "    plt.show()"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "ea70d47c1026074199160e48050b9f1be75d4ba7d6f2081b88238ca77789226b"
  },
  "kernelspec": {
   "display_name": "Python 3.7.11 ('pytorch-gpu')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
